package com.guoranhao.tool.rpc;

import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.extension.Activate;
import com.alibaba.dubbo.rpc.*;
import com.alibaba.fastjson.JSON;
import com.guoranhao.tool.utils.LogUtil;
import com.guoranhao.tool.utils.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

import java.util.Map;
import java.util.UUID;

@Activate(group = Constants.PROVIDER)
public class RpcServerInterceptor implements Filter {


    private static final Logger logger = LoggerFactory.getLogger(RpcServerInterceptor.class);

    public RpcServerInterceptor() {
    }

    @Override
    public Result invoke(Invoker<?> arg0, Invocation arg1) throws RpcException {
        Result result;
        Map<String, String> att = arg1.getAttachments();
        setTraceId(arg1);
        MDC.put("TraceId", att.get("TraceId"));
        try {
            String[] interfaces = arg0.getUrl().getParameter("interface").split("\\.");
            String address = RpcContext.getContext().getRemoteAddressString();
            LogUtil.info(logger, "[server][{0}][{1}]receive:{2}", address, (interfaces.length > 0 ?
                    interfaces[interfaces.length - 1] : "") + "." + arg1.getMethodName(), JSON.toJSON(arg1.getArguments()));
            //开始计时
            long beginTime = System.currentTimeMillis();
            result = arg0.invoke(arg1);
            //结束计时
            long endTime = System.currentTimeMillis();
            String value = "";
            if(result.getValue() != null){
                Object o = JSON.toJSON(result.getValue());
                if(o != null){
                    value = o.toString();
                }
            }
            if (value.length() > 5000) {
                LogUtil.info(logger, "[server][{0}](T:{1})return:{2}", (interfaces.length > 0 ?
                        interfaces[interfaces.length - 1] : "") + "." + arg1.getMethodName(), endTime - beginTime, value.substring(0, 1000) + "......");
                LogUtil.debug(logger, "[server][{0}](T:{1})return:{2}", (interfaces.length > 0 ?
                        interfaces[interfaces.length - 1] : "") + "." + arg1.getMethodName(), endTime - beginTime, value);
            } else {
                LogUtil.info(logger, "[server][{0}](T:{1})return:{2}", (interfaces.length > 0 ?
                        interfaces[interfaces.length - 1] : "") + "." + arg1.getMethodName(), endTime - beginTime, value);
            }
        } finally {
            MDC.remove("TraceId");
        }
        return result;
    }

    /**
     * 添加traceId
     *
     * @param arg1
     */
    private void setTraceId(Invocation arg1) {
        if (StringUtil.isEmpty(arg1.getAttachment("TraceId"))) {
            Map<String, String> at = arg1.getAttachments();
            at.put("TraceId", UUID.randomUUID().toString().replace("-", ""));
        }
    }
}